using System;
using System.Collections.Generic;
using UnityEngine;

namespace Utilss
{
    public class Timer
    {
        private static Timer ins;
        /// <summary>
        /// ��ʱ���ֵ�
        /// </summary>
        private Dictionary<int, Tick> tickDict = new Dictionary<int, Tick>();
        private float curtime;
        /// <summary>
        /// �ӳٶ�ʱ���ֵ�
        /// </summary>
        private Dictionary<int, Tick> deltaTickDic = new Dictionary<int, Tick>();
        /// <summary>
        /// ��ǰ�ӳٵ�ʱ��
        /// </summary>
        private float deltaTime;
        /// <summary>
        /// δ����ʱ��
        /// </summary>
        private float unscaledTime;
        private int timerid;

        List<int> dellist = new List<int>();
        List<int> templist = new List<int>();
        public float DeltaTime
        {
            get
            {
                return Time.deltaTime;
            }

        }
        public static Timer Instance
        {
            get
            {
                if (ins == null)
                {
                    ins = new Timer();
                }
                return ins;
            }
        }

        public bool Init()
        {
            timerid = 0;
            curtime = Time.unscaledTime;
            unscaledTime = Time.unscaledTime;
            deltaTime = Time.time;
            return true;
        }

        /// <summary>
        /// ���Ӷ�ʱ��,�ö�ʱ������ʱ������Ӱ��
        /// </summary>
        /// <param name="interval">��ʱ��ʱ��������λ�룩</param>
        /// <param name="count">��ʱ��ִ�д���,0���޴���</param>
        /// <param name="start">��ʱ����ʼ�ȴ�ʱ��</param>
        /// <param name="func">��ʱ���ص�����</param>
        /// <returns></returns>
        public int AddTimer(float interval, long count, float start, TimerCallBack func)
        {
            
            if (interval < 0 || count < 0 || start < 0)
            {
                Debug.LogError("error add timer args:" + interval + count + start);
                return 0;
            }
            Tick tick = new Tick();
            if (tick == null)
            {
                return 0;
            }
            timerid++;
            tick.tid = timerid;
            tick.interval = interval;
            tick.start = unscaledTime + start;
            tick.count = count;
            tick.cbfunc = func;
            tickDict.Add(tick.tid, tick);
            return tick.tid;
        }
        /// <summary>
        /// ���Ӷ�ʱ��,�ö�ʱ����ʱ������Ӱ��
        /// </summary>
        /// <param name="interval"></param>
        /// <param name="count"></param>
        /// <param name="start"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public int AddDeltaTimer(float interval, int count, float start, TimerCallBack func)
        {
            Debug.Log("�Ӷ�ʱ��");
            if (interval < 0 || count < 0 || start < 0)
            {
                Debug.LogError("error add timer args:" + interval + count + start);
                return 0;
            }
            Tick tick = new Tick();
            if (tick == null)
            {
                return 0;
            }
            timerid++;
            tick.tid = timerid;
            tick.interval = interval;
            tick.start = deltaTime + start;
            tick.count = count;
            tick.cbfunc = func;

            if (deltaTickDic.ContainsKey(tick.tid))
            {
                Debug.LogError("ssssssssss");
            }
            deltaTickDic.Add(tick.tid, tick);
            Debug.Log("�Ӷ�ʱ������");
            return tick.tid;
        }

        /// <summary>
        /// ���ö�ʱ��Ϊ����״̬
        /// </summary>
        /// <param name="tid"></param>
        public void SetFixTimer(int tid)
        {
            Tick tick = null;
            if (tickDict.ContainsKey(tid))
            {
                tick = tickDict[tid];
            }
            else if (deltaTickDic.ContainsKey(tid))
            {
                tick = deltaTickDic[tid];
            }
            if (tick == null)
            {
                Debug.LogError("pause timer no id:" + tid);
                return;
            }
            tick.fix = true;
        }

        /// <summary>
        /// ȡ�����ж�ʱ��,���Ϊ�����ĳ���
        /// </summary>
        public void CancelAllTimer()
        {
            List<int> _list = new List<int>();
            foreach (var item in tickDict)
            {
                Tick tick = item.Value;
                if (tick.fix == false)
                {
                    _list.Add(tick.tid);
                }
            }

            foreach (var item in deltaTickDic)
            {
                Tick tick = item.Value;
                if (tick.fix == false)
                {
                    _list.Add(tick.tid);
                }
            }

            foreach (var item in _list)
            {
                int tid = item;
                CancelTimer(tid);
            }
        }

        /// <summary>
        /// ȡ��������ʱ��
        /// </summary>
        /// <param name="tid"></param>
        public void CancelTimer(int tid)
        {
            if (tickDict.ContainsKey(tid))
            {
                tickDict.Remove(tid);
            }
            else if (deltaTickDic.ContainsKey(tid))
            {
                deltaTickDic.Remove(tid);
            }
            else
            {
                //Output.Error("do delete timer no id:", tid);
            }
        }

        /// <summary>
        /// ��ͣ������ʱ��
        /// </summary>
        /// <param name="tid"></param>
        public void PauseTimer(int tid)
        {
            Tick tick = null;
            if (tickDict.ContainsKey(tid))
            {
                tick = tickDict[tid];
            }
            else if (deltaTickDic.ContainsKey(tid))
            {
                tick = deltaTickDic[tid];
            }
            if (tick == null)
            {
                Debug.LogError("pause timer no id:" + tid);
                return;
            }
            tick.pause = true;
        }

        /// <summary>
        /// ��ͣ���ж�ʱ��
        /// </summary>
        public void PauseAllTimer()
        {
            List<int> _list = new List<int>();
            foreach (var item in tickDict)
            {
                Tick tick = item.Value;
                _list.Add(tick.tid);
            }
            foreach (var item in deltaTickDic)
            {
                Tick tick = item.Value;
                _list.Add(tick.tid);
            }

            foreach (var item in _list)
            {
                int tid = item;
                PauseTimer(tid);
            }
        }

        /// <summary>
        /// �ָ�������ʱ��
        /// </summary>
        /// <param name="tid"></param>
        public void RecoverTimer(int tid)
        {
            Tick tick = null;
            if (tickDict.ContainsKey(tid))
            {
                tick = tickDict[tid];
            }
            else if (deltaTickDic.ContainsKey(tid))
            {
                tick = deltaTickDic[tid];
            }
            if (tick == null)
            {
                Debug.LogError("recover timer no id:" + tid);
                return;
            }
            tick.pause = false;
        }

        /// <summary>
        /// �ָ����ж�ʱ��
        /// </summary>
        public void RecoverAllTimer()
        {
            List<int> _list = new List<int>();
            foreach (var item in tickDict)
            {
                Tick tick = item.Value;
                _list.Add(tick.tid);
            }
            foreach (var item in deltaTickDic)
            {
                Tick tick = item.Value;
                _list.Add(tick.tid);
            }

            foreach (var item in _list)
            {
                int tid = item;
                RecoverTimer(tid);
            }
        }

        public void DoUpdate()
        {
            deltaTime = Time.time;
            if (deltaTickDic.Count <= 0) return;

            dellist.Clear();
            templist.Clear();

            foreach (var item in deltaTickDic)
            {
                Tick tick = item.Value;
                templist.Add(tick.tid);
            }


            foreach (var item in templist)
            {
                int tid = item;
                Tick tick;
                if (!deltaTickDic.TryGetValue(tid, out tick))
                {
                    continue;
                };

                if (tick.pause == true) continue;
                if (tick.start <= deltaTime)
                {
                    tick.cbfunc();
                    tick.count--;
                    tick.start += tick.interval;
                    if (tick.count == 0)
                    {
                        dellist.Add(tick.tid);
                    }
                }
            }

            foreach (int tid in dellist)
            {
                if (deltaTickDic.ContainsKey(tid) == false)
                {
                    //Output.Error("auto delete timer no id:", tid);
                    continue;
                }
                deltaTickDic.Remove(tid);
            }
        }
        public string GetCurTime()
        {
            return DateTime.Now.ToString("HH:mm:ss, dd/MM/yyyy");
        }
        
        public void DoFixUpdate()
        {
            curtime = Time.unscaledTime;
            unscaledTime = curtime;
            if (tickDict.Count <= 0) return;

            dellist.Clear();
            templist.Clear();

            foreach (var item in tickDict)
            {
                Tick tick = item.Value;
                templist.Add(tick.tid);
            }

            foreach (var item in templist)
            {
                int tid = item;
                Tick tick;
                if (!tickDict.TryGetValue(tid, out tick))
                {
                    //Debug.LogError("find timer no id:" + tid);
                    continue;
                };

                if (tick.pause == true) continue;
                if (tick.start <= curtime)
                {
                    tick.cbfunc();
                    tick.count--;
                    tick.start += tick.interval;
                    if (tick.count == 0)
                    {
                        dellist.Add(tick.tid);
                    }
                }
            }

            foreach (int tid in dellist)
            {
                if (tickDict.ContainsKey(tid) == false)
                {
                    //Output.Error("auto delete timer no id:", tid);
                    continue;
                }
                tickDict.Remove(tid);
            }
        }
        /// <summary>
        /// ������ת��Ϊ00:00:00��ʽ
        /// </summary>
        /// <param name="time">����</param>
        /// <returns>00:00:00</returns>
        public string ToTimeFormat(long time)
        {
            //����ȡ��
            long seconds = time;
            //һСʱΪ3600�� ������3600ȡ����ΪСʱ
            long hour = seconds / 3600;
            //һ����Ϊ60�� ������3600ȡ���ٶ�60ȡ����Ϊ����
            long minute = seconds % 3600 / 60;
            //��3600ȡ���ٶ�60ȡ�༴Ϊ����
            seconds = seconds % 3600 % 60;
            //����00:00:00ʱ���ʽ
            return string.Format("{0:D2}:{1:D2}:{2:D2}", hour, minute, seconds);
        }

        public static long currentTimeMillis
        {
            get { return TimerUtils.currentTimeMillis; }
        }

    }


}
